package com.niit.scala

/**
 * Date:2025/3/17
 * Author：Ys
 * Description:
 *
 *    类与对象：
 *       Scala中类的定义，类中的成员变量和成员方法的定义
 *         构造器：主构造器  辅助构造器
 */
object Base05 {

  // 类的声明
  // 定义一个空类
  class Person  // 定义一个空类

  //在类中定义成员变量和成员方法
  class Student{
    //var name = ""
    //var age = 0
    //优雅的定义成员  _作为初始变量的值  _对要定义的变量的值进行占位，充当的占位符的作用，
    //如果 _的形式去充当占位符的时候，在定义成员变量时一定要写变量类型
    private var name:String = _
    var age:Int = _

    def setName(name:String): Unit = {
      this.name = name
    }
    def getName(): String = {
      return this.name
    }

    def printInfo(): Unit = {
      // this 当前类的引用
      println("姓名"+this.name+",年龄："+this.age)
    }
  }

  /*Scala中构造器：
     主构造器： 格式：class 类名(var/val 参数名:参数类型,var/val 参数名:类型 = 默认值){}
   */
  class Teacher(var name:String,var age:Int,var addr:String = "广西"){

    //辅助构造器： 辅助构造器方法必须叫 this  格式：def this(参数:变量类型,参数:变量类型)
    //在辅助构造器中第一行必须调用主构造器
    def this(phone:String){
      this("王五",20,"广西")
      println("辅助构造器",phone)
    }

  }

  /*
  在Scala是没有static 关键字  如果想使用静态只能够定义单例对象
    object 对象名{}
    调用:对象名.属性
   */
 object Dog{
    val leg_num = 4

    def printInfo(): Unit = {
      println("Dog.printInfo")
    }
  }

  /*
    在Java中，类里面可以定义成员变量和静态变量以及成员方法和静态方法，如果想在Scala实现这一效果就要用到  伴生对象
        一个class 和 一个 object 的名字是相同，那么就叫做伴生，objec为类的伴生对象，类的为object的伴生类
        并且 这个class和 object必须在同一个文件当中
        伴生对象和伴生类可以访问到对方私有的成员变量和方法。
   */
  class Generals{

    def gan(): Unit = {
      println("拿着"+Generals.armsName)
      //Generals.printInfo()
    }

  }
  // ↑  互生伴生  ↓
  object Generals{

    private var armsName = "大刀"
    //在伴生对象中，privar [this] 表示，表示这个方法只能被这个伴生对象访问
    private [this] def printInfo(): Unit = {
      println("Generals.printInfo")
    }

    def arms(): Unit = {
      printInfo()
    }

  }

  // apply方法免去new的方式进行实例化
  class Animal(var name:String,var age:Int = 2) // 只有类才能实例化
  object Animal{
    def apply(name:String,age:Int): Animal = {
      //在伴生对象中进行的实例化
      new Animal(name,age)
    }
  }

  def main(args: Array[String]): Unit = {
    //如果我们定义的类 没有构造器 在实例化的时候可以省略括号
    val p1 = new Person

    val stu1 = new Student
    //stu1.name = "张三"
    stu1.setName("张三")
    stu1.age = 20
    stu1.printInfo()
    stu1.age = 35
    stu1.printInfo()

    val teacher = new Teacher("李四",30)
    println(s"姓名：${teacher.name},年龄：${teacher.age},地址：${teacher.addr}")
    teacher.addr = "北京"
    println(s"姓名：${teacher.name},年龄：${teacher.age},地址：${teacher.addr}")
    val teacher2 = new Teacher("133333333")
    //辅助构造器中的变量仅仅是作为参数，不能像主构造器中的变量一样，可以访问。
    //println(s"姓名：${teacher2.name},年龄：${teacher2.age},地址：${teacher2.addr},电话：${teacher2.phone}")

    println(Dog.leg_num)
    Dog.printInfo()

    var generals = new Generals
    generals.gan()

    val anni = Animal("大黄",2)
    println(s"name:${anni.name},age:${anni.age}")

  }

}
